import * as Cesium from 'cesium'
import axios from 'axios'
import { AMapKey } from '@/api/request.js'

// 地理编码 API 服务地址
const AMapGeocodeApi = 'https://restapi.amap.com/v3/geocode/geo'

/*
  1. 通过经纬度坐标定位地址 直接调用 longitudeAndLatitudePositioning 方法
    例：
      longitudeAndLatitudePositioning(this.viewer, {
        pos: [120.982894, 31.546886]
      }).then(res => {
        console.log('返回的为定位的经纬度坐标信息：', res);
      })
  2. 通过地址定位 需要先调用 transAddressToCode 方法，查询到地址的经纬度，可能为多个 ，所以需要用户选取相应的地址后，再进行定位
    例：   geocodes 返回的为多个地址的code信息
      transAddressToCode({
        address: '杭州市智慧信息产业园'
      }).then(res => {
        const address = res.geocodes[0] || {}
        let pos = address.location || ''
        pos = pos.split(',')
        setTimeout(() => {
          longitudeAndLatitudePositioning(this.viewer, {
            pos
          })
        }, 3000)
      }).catch(err => {
        console.error(err)
      })
*/

export const longitudeAndLatitudePositioning = (viewer, options = {}) => {
  /*
    参数说明：
      1. viwer 观察器
      2. options
         pos：需要定位的位置 0:经度 1:纬度 默认为：lon = 119.982894, lat = 30.546886
         duration：飞的过渡动画时间  默认为 2s
         height：地图的高度 10000
  */
  const { pos = [], duration = 2, height = 10000 } = options

  const [lon = 119.982894, lat = 30.546886] = pos

  return new Promise((resolve, reject) => {
    viewer.camera.flyTo({
      duration, // 飞的过渡动画时间
      destination: Cesium.Cartesian3.fromDegrees(
        lon, // 地图经度
        lat, // 地图维度
        height // 地图高度
      ),
      complete: () => {
        resolve(pos)
      },
      cancel: res => {
        reject(res)
      }
    })
  })
}

// 通过地址查询经纬度
export const transAddressToCode = params => {
  /*
    参数说明：
      key 高德地图应用申请的key
      address 所要搜索的地址信息名称 字符串 例如：杭州市智慧信息产业园
      city  所要搜索的地址的城市 例如：杭州市

    注意：返回的信息可能查询不到为 0 ，需要判断 返回的 count 信息的值
  */
  params = {
    key: AMapKey, // 高德地图应用申请的key
    ...params
  }
  return new Promise((resolve, reject) => {
    axios
      .get(AMapGeocodeApi, {
        params
      })
      .then(
        response => {
          let data = response.data || {}
          data.geocodes = data.geocodes.map(item => {
            let point = item.location.split(',')
            point = gcj2wgs(point)
            item.point = point
            return item
          })
          resolve(data)
        },
        err => {
          reject(err)
        }
      )
      .catch(error => {
        reject(error)
      })
  })
}

// 坐标转换==================================
let x_PI = (3.14159265358979324 * 3000.0) / 180.0
let PI = 3.1415926535897932384626
let a = 6378245.0
let ee = 0.00669342162296594323

function transformWD (lng, lat) {
  let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng))
  ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0
  ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0
  ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0
  return ret
}

function transformJD (lng, lat) {
  let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
  ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0
  ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0
  ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0
  return ret
}

function wgs2gcj (arrdata) {
  let lng = Number(arrdata[0])
  let lat = Number(arrdata[1])
  let dlat = transformWD(lng - 105.0, lat - 35.0)
  let dlng = transformJD(lng - 105.0, lat - 35.0)
  let radlat = (lat / 180.0) * PI
  let magic = Math.sin(radlat)
  magic = 1 - ee * magic * magic
  let sqrtmagic = Math.sqrt(magic)
  dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI)
  dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI)
  let mglat = lat + dlat
  let mglng = lng + dlng

  mglng = Number(mglng.toFixed(6))
  mglat = Number(mglat.toFixed(6))
  return [mglng, mglat]
}

function gcj2wgs (arrdata) {
  let lng = Number(arrdata[0])
  let lat = Number(arrdata[1])
  let dlat = transformWD(lng - 105.0, lat - 35.0)
  let dlng = transformJD(lng - 105.0, lat - 35.0)
  let radlat = (lat / 180.0) * PI
  let magic = Math.sin(radlat)
  magic = 1 - ee * magic * magic
  let sqrtmagic = Math.sqrt(magic)
  dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI)
  dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI)

  let mglat = lat + dlat
  let mglng = lng + dlng

  let jd = lng * 2 - mglng
  let wd = lat * 2 - mglat

  jd = Number(jd.toFixed(6))
  wd = Number(wd.toFixed(6))
  return [jd, wd]
}
export {wgs2gcj}
